﻿using System;
using System.Diagnostics;
using System.Linq;

namespace Sigmoid
{
    /// <summary>
    /// Konsolen-Testprogram für Sigmoid und FastSigmoid.
    /// </summary>
    class Program
    {
        /// <summary>
        /// Konsolen-Testprogram für Sigmoid und FastSigmoid.
        /// </summary>
        /// <param name="args">The arguments.</param>
        static void Main(string[] args) {
            Stopwatch watch = new Stopwatch();
            Random rand = new Random();
            double[] inputs = new double[1024*1024*16];
            double[] results1 = new double[inputs.Length];
            double[] results2 = new double[inputs.Length];
            for (int i = 0; i < inputs.Length; i++) {
                inputs[i] = rand.NextDouble() * 2.0 - 1.0; // Zufallszahl von -1 bis +1
            }

            watch.Start();
            for (int i = 0; i < inputs.Length; i++) {
                results1[i] = Sigmoid.ESigmoid(inputs[i], N:1.0, T:5.0);
            }
            watch.Stop();
            Console.WriteLine("{0} Werte mit Sigmoid in {1} ms berechnet.", inputs.Length, watch.ElapsedMilliseconds);
            Console.WriteLine("Durchschnittsergebnis: {0:F4}", results1.Average());
            double sum1 = 0.0;
            for (int i = 0; i < results1.Length; i++) {
                sum1 += Math.Abs(results1[i]);
            }
            Console.WriteLine("Summe der Absoluten: {0:F4}", sum1);
            watch.Reset();

            watch.Start();
            for (int i = 0; i < inputs.Length; i++) {
                results2[i] = Sigmoid.FastESigmoid(inputs[i], N: 1.0, T: 5.0);
            }
            watch.Stop();
            Console.WriteLine("{0} Werte mit FastSigmoid in {1} ms berechnet.", inputs.Length, watch.ElapsedMilliseconds);
            Console.WriteLine("Durchschnittsergebnis: {0:F4}", results2.Average());
            double sum2 = 0.0;
            for (int i = 0; i < results2.Length; i++) {
                sum2 += Math.Abs(results2[i]);
            }
            Console.WriteLine("Summe der Absoluten: {0:F4}", sum2);

            double diffSum = 0.0;
            for (int i = 0; i < results1.Length; i++) {
                double diff = results1[i] - results2[i];
                diff *= diff;
                diffSum += diff;
            }
            diffSum = diffSum / results1.Length;
            Console.WriteLine("Mittlere quadratische Abweichung: {0:F6}", diffSum);

            Console.ReadKey(true);
            // mittl. quadr. Abweichung etwa 0.000371 -> gut
            // Durchschnittsergebnis. zufällig gleichverteilter Input von -1 bis +1.
            // Jeweils symmetrische Funktion -> Erwarteter Durchschnitt ist 0.0
            // Sigmoid: etwa 0.0001
            // Fast Sigmoid etwa: 0.0173 -> deutet ev. auf Rundungsfehler hin?
            // Summen unterscheiden sich gewaltig! Erklärung unbekannt.
        }
    }
}
